﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OhioState.Tiling;
using UnityEngine;

namespace OhioState.Tiling
{
    class PerlinNoiseTileSetBuilder:Wang2DGridTileSetBuilder<Texture2D, List<int>>
    {
        public PerlinNoiseTileSetBuilder(int horizontalColor, int verticalColor, int resolution, EdgeColorsBuilder<List<int>> edgeBuilder)
            : base(horizontalColor, verticalColor, edgeBuilder)
        {
            this.resolution = resolution;
        }
        public void BuildEdges()
        {
            PerlinNoiseEdgeColorBuilder noiseEdgeBuilder = (PerlinNoiseEdgeColorBuilder)edgeBuilder;
            horizontalColors = noiseEdgeBuilder.BuildEdgeColor(NumberOfHorizontalColor);
          
            
            verticalColors = noiseEdgeBuilder.BuildEdgeColor(NumberOfVerticalColor);
            perm = new int[]{ 151,160,137,91,90,15,
          131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
          190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
          88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
          77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
          102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
          135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
          5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
          223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
          129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
          251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
          49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
          138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180};
            
        }
        public override ITileSet<Texture2D> Build()
        {
            BuildEdges();
            List<ITile<Texture2D>> tiles = new List<ITile<Texture2D>>();
            for (int top = 0; top < NumberOfHorizontalColor; top++)
            {
                for (int left = 0; left < NumberOfVerticalColor; left++)
                {
                    for (int bottom = 0; bottom < NumberOfHorizontalColor; bottom++)
                    {
                        for (int right = 0; right < NumberOfVerticalColor; right++)
                        {
                            Texture2D texture = BuildSingleTile(verticalColors[left], verticalColors[right], horizontalColors[top], horizontalColors[bottom]);
                            PerlinNoiseTile tile = new PerlinNoiseTile(horizontalColors[top], horizontalColors[bottom], verticalColors[left], verticalColors[right], texture);
                            tiles.Add((ITile<Texture2D>)tile);
                            //tile.Print();
                        }
                    }
                }
            }
            PerlinNoiseTileSet noiseTileSet = new PerlinNoiseTileSet(tiles, verticalColors, horizontalColors);
            return noiseTileSet;

        }

        private Texture2D BuildSingleTile(List<int> left, List<int> right, List<int> top, List<int> bottom)
        {
            Texture2D texture = new Texture2D(resolution, resolution);
            System.Random rng = new System.Random();
            for (int i = 1; i < resolution-1; i++)
            {
                for (int j = 1; j < resolution-1; j++)
                {
                    int idx = rng.Next(256);
                    idx = perm[idx];
                    float t = (float)idx/255.0f;
                    Color c = new Color(t,t,t);
                    texture.SetPixel(i, j, c);
                }
            }
            for (int i = 0; i < resolution; i++)
            {
                int idx = perm[left[i]];
                Color c = new Color(idx / 255.0f, idx / 255.0f, idx / 255.0f);
                //c = Color.red;
                Color leftColor = c;
                texture.SetPixel(resolution - 1, i, leftColor);

                idx = perm[right[i]];
                c = new Color(idx / 255.0f, idx / 255.0f, idx / 255.0f);
               // c = Color.green;
                Color rightColor = c;
                texture.SetPixel(0,i, rightColor);

                idx = perm[bottom[i]];
                c = new Color(idx / 255.0f, idx / 255.0f, idx / 255.0f);
                //c = Color.blue;
                Color bottomColor = c;
                texture.SetPixel(i, resolution - 1,  bottomColor);

                idx = perm[top[i]];
                c = new Color(idx / 255.0f, idx / 255.0f, idx / 255.0f);
                //c = Color.magenta;
                Color topColor = c;
                texture.SetPixel(i, 0,topColor);
            }
            //Debug.Log("left color");
            //PrintEdge(left);
            //Debug.Log("right color");
            //PrintEdge(right);
            //Debug.Log("top color");
            //PrintEdge(top);
            //Debug.Log("bottom color");
            //PrintEdge(bottom);
            

            return texture;
        }
        
        public void PrintEdge(List<int> edgeColor)
        {
            StringBuilder s = new StringBuilder();
            for (int i = 0; i < edgeColor.Count(); i++)
            {
                s.Append(edgeColor[i]+" ");
            }
            Debug.Log(s.ToString());
        }
        private int resolution;
        private int[] perm;
    }
}
